import socket
import struct
import select
import time

# 定义服务器的 IP 和端口
host = '127.0.0.1'
port = 6666

# 创建 TCP socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 端口复用
server_socket.setblocking(False)  # 设置为非阻塞模式

# 初始化数据变量，使用完数据后要将数据清零
get_check1, get_speed, get_mode, get_doit = 0.0, 0.0, 0.0, 0.0
get_longitude, get_latitude, get_altitude = [0.0]*4, [0.0]*4, [0.0]*4
get_check2 = 0.0
# 使用完数据后要初始化
send_check1, send_speed, send_mode, send_doit = 888.0, 0.0, 0.0, 1.0
send_longitude, send_latitude, send_altitude = [0.0]*4, [0.0]*4, [0.0]*4
send_check2 = 666.0

# 写好包头包尾
def send_datas_init():
    global send_check1
    global send_speed
    global send_mode
    global send_doit
    global send_longitude
    global send_latitude
    global send_altitude
    global send_check2
    send_check1 = 888.0     # 包头，888.0有效
    send_speed = 0.0
    send_mode = 0.0        # 飞行模式/任务：1.0表示...2.0表示...
    send_doit = 0.0        # 执行确认位(1.0表示有效，0.0表示无效)
    send_longitude = [0.0,0.0,0.0,0.0]   # 新建一个列表来存储经度,longitude[0]和latitude[0]为一对
    send_latitude =  [0.0,0.0,0.0,0.0]   # 列表存储纬度
    send_altitude =  [0.0,0.0,0.0,0.0]   # 列表存储海拔（高度）
    send_check2 = 666.0     # 包尾，666.0有效

def get_datas_to_0():
    global get_check1
    global get_speed
    global get_mode
    global get_doit
    global get_longitude
    global get_latitude
    global get_altitude
    global get_check2
    get_check1 = 0.0     # 包头，888.0有效
    get_speed = 0.0
    get_mode = 0.0        # 飞行模式/任务：1.0表示...2.0表示...
    get_doit = 0.0        # 执行确认位(1.0表示有效，0.0表示无效)
    get_longitude = [0.0,0.0,0.0,0.0]   # 新建一个列表来存储经度,longitude[0]和latitude[0]为一对
    get_latitude =  [0.0,0.0,0.0,0.0]   # 列表存储纬度
    get_altitude =  [0.0,0.0,0.0,0.0]   # 列表存储海拔（高度）
    get_check2 = 0.0     # 包尾，666.0有效

# 发送数据
def send_data(client_socket, data_to_send):
    try:
        packed_data = struct.pack('>17d', *data_to_send)
        client_socket.sendall(packed_data)
        print(f"Sent data: {data_to_send}")
    except BlockingIOError:
        print("发送数据时阻塞，请稍后再试。")
    except Exception as e:
        print(f"发送数据时出错: {e}")

# 接收数据
def receive_data(client_socket):
    global get_check1, get_speed, get_mode, get_doit
    global get_longitude, get_latitude, get_altitude, get_check2

    try:
        readable, _, _ = select.select([client_socket], [], [], 0.05)
        if readable:
            response = client_socket.recv(136)
            if response:
                unpacked_data = struct.unpack('>17d', response)
                get_check1, get_speed, get_mode, get_doit, \
                get_longitude[0], get_latitude[0], get_altitude[0], \
                get_longitude[1], get_latitude[1], get_altitude[1], \
                get_longitude[2], get_latitude[2], get_altitude[2], \
                get_longitude[3], get_latitude[3], get_altitude[3],get_check2 = unpacked_data
                # print("接收到的数据:")
                # print(f"  经度: {get_longitude}, 纬度: {get_latitude}, 高度: {get_altitude}")
                # print(f"  速度: {get_speed}, 飞行模式: {get_mode}")
            else:
                print("客户端已断开连接。")
                return False
    except BlockingIOError:
        print("接收数据时阻塞，请稍后再试。")
    except Exception as e:
        print(f"接收数据时出错: {e}")
        return False
    return True

should_send = 1     # 应该发送数据

# 启动服务器
def start_server():
    server_socket.bind((host, port))
    server_socket.listen(5)
    print(f"服务器启动，监听 {host}:{port}...")
    global should_send
    try:
        while True:
            try:
                client_socket, addr = server_socket.accept()
                client_socket.setblocking(False)  # 设置客户端 socket 为非阻塞
                should_send = 1     # 应该发送数据
                print(f"连接来自 {addr}")
            except BlockingIOError:
                time.sleep(0.1)
                continue

            # 循环处理客户端连接
            while True:
                # 尝试接收数据，若客户端断开连接则跳出循环，（逻辑代码在这个循环里写）
                if not receive_data(client_socket):
                    break
                # 检查校验位
                if get_check1 == 888.0 and get_check2 == 666.0 and get_doit == 1.0:     # 数据为应答位
                    send_datas_init()
                    print("should_send = 0")
                    should_send = 0
                    get_datas_to_0()        # 使用完数据后要清零
                
                if should_send == 1:
                    send_datas_init()
                    send_longitude[0] = 8.545593
                    send_latitude[0] = 47.397742
                    send_altitude[0] = 565.365917
                    send_longitude[1] = 8.547984
                    send_latitude[1] = 47.398159
                    send_altitude[1] = 565.365917
                    send_longitude[2] = 8.546871
                    send_latitude[2] = 47.396556
                    send_altitude[2] = 565.365917
                    send_longitude[3] = 8.545593
                    send_latitude[3] = 47.397742
                    send_altitude[3] = 565.365911
                    send_doit = 1.0
                    send_mode = 1.0
                    data_to_send = [send_check1, send_speed, send_mode,send_doit,\
                                    send_longitude[0], send_latitude[0],send_altitude[0],\
                                    send_longitude[1], send_latitude[1],send_altitude[1],\
                                    send_longitude[2], send_latitude[2],send_altitude[2],\
                                    send_longitude[3], send_latitude[3],send_altitude[3],send_check2]
                    send_data(client_socket, data_to_send)

                time.sleep(0.1)

            client_socket.close()
            print(f"关闭与 {addr} 的连接，准备接收下一个连接...")

    except KeyboardInterrupt:
        print("\n服务器正在关闭...")
    finally:
        server_socket.close()
        print("服务器已关闭。")

if __name__ == "__main__":
    start_server()


    # msg.gps[0].latitude = 47.397742
    # msg.gps[0].longitude = 8.545593
    # msg.gps[0].altitude = 565.365917
    # # 47°23'51.4"N 8°32'52.2"E
    # msg.gps[1].latitude = 47.398159
    # msg.gps[1].longitude = 8.547984
    # msg.gps[1].altitude = 565.365917
    # # 47°23'51.9"N 8°32'44.1"E
    # msg.gps[2].latitude = 47.396556
    # msg.gps[2].longitude =  8.546871
    # msg.gps[2].altitude = 565.365917
    # # 初始lat：47.397742，lon：8.545593,alt:535.365917
    # msg.gps[3].latitude = 47.397742
    # msg.gps[3].longitude = 8.545593
    # msg.gps[3].altitude = 565.365917